package com.xg.mina;

import com.xg.mina.message.Constant;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.StringUtils;
import org.apache.mina.core.buffer.IoBuffer;
import org.bouncycastle.util.BigIntegers;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Random;

public class Utils {
    /**
     * 东方卫视 rtmp://58.200.131.2:1935/livetv/dftv
     * 广东卫视 rtmp://58.200.131.2:1935/livetv/gdtv
     * 广西卫视 rtmp://58.200.131.2:1935/livetv/dftv
     * 湖南卫视 rtmp://58.200.131.2:1935/livetv/hunantv
     */
    public static final String rtmp_url = "rtmp://58.200.131.2:1935/livetv/hunantv";

    /**
     * 把byte转为字符串的bit
     */
    public static String byteToBit(byte b) {
        return ""
                + (byte) ((b >> 7) & 0x1) + (byte) ((b >> 6) & 0x1)
                + (byte) ((b >> 5) & 0x1) + (byte) ((b >> 4) & 0x1)
                + (byte) ((b >> 3) & 0x1) + (byte) ((b >> 2) & 0x1)
                + (byte) ((b >> 1) & 0x1) + (byte) ((b >> 0) & 0x1);
    }

    public static byte binaryByteToByte(String str) {
        if (str.length() != 8) {
            throw new RuntimeException("byte字符串必须是8位：" + str);
        }
        return (byte) Short.parseShort(str, 2);
    }

    public static byte[] binaryIntToByte(String str, int length) {
        byte[] bytes = new byte[length];
        for (int i = 0; i < length; i++) {
            int start = i * 8;
            int end = start + 8;
            String subString = StringUtils.substring(str, start, end);
            bytes[i] = binaryByteToByte(subString);
            bytes[length - i - 1] = binaryByteToByte(subString);
        }
        return bytes;
    }

    public static String tobinaryString(Byte num, int length) {
        String binaryString = Integer.toBinaryString(num);
        if (binaryString.length() > length) {
            throw new RuntimeException("当前整数：" + num + "\t位数为：" + binaryString.length() + "\t期望位数：" + length);
        }
        return StringUtils.leftPad(binaryString, length, '0');
    }

    public static String tobinaryString(Integer num, int length) {
        String binaryString = Integer.toBinaryString(num);
        if (binaryString.length() > length) {
            throw new RuntimeException("当前整数：" + num + "\t位数为：" + binaryString.length() + "\t期望位数：" + length);
        }
        return StringUtils.leftPad(binaryString, length, '0');
    }

    public static byte[] int3bytes(int num) {
        IoBuffer buffer = IoBuffer.allocate(4);
        buffer.putUnsignedInt(num);
        IoBuffer flip = buffer.flip();
        byte[] src = flip.array();
        byte[] dest = new byte[3];
        System.arraycopy(src, 1, dest, 0, 3);
        return dest;
    }

    public static byte[] intTobytes(int val) {
        byte[] b = new byte[4];
        b[0] = (byte) (val & 0xff);
        b[1] = (byte) ((val >> 8) & 0xff);
        b[2] = (byte) ((val >> 16) & 0xff);
        b[3] = (byte) ((val >> 24) & 0xff);
        return b;
    }

    public static byte[] int2Bytes(int num) {
        /*byte[] bytes = new byte[4];
        //通过移位运算，截取低8位的方式，将int保存到byte数组
        bytes[0] = (byte)(num >>> 24);
        bytes[1] = (byte)(num >>> 16);
        bytes[2] = (byte)(num >>> 8);
        bytes[3] = (byte)num;
        return bytes;*/
        IoBuffer allocate = IoBuffer.allocate(4);
        allocate.putUnsignedInt(num);
        return allocate.array();
    }

    public static void printBytes(byte[] transaction) {
        for (int i = 0; i < transaction.length; i++) {
            System.out.print(StringUtils.leftPad(Integer.toHexString(transaction[i]), 2, '0') + "\t");
        }
    }

    public static String byteToString(byte[] transaction) {
        StringBuilder sb = new StringBuilder("[");
        for (int i = 0; i < transaction.length; i++) {
            sb.append(Integer.toHexString(transaction[i])+" ");
        }
        sb.append("]");
        return sb.toString();
    }

    public static byte int1bytes(int num) {
        if (num > 255) {
            throw new RuntimeException("1个byte不能大于255");
        }
        String str = tobinaryString(num, 8);
        return binaryByteToByte(str);
    }

    public static byte[] int2bytes(int num) {
        if (num > 255) {
            throw new RuntimeException("1个byte不能大于255");
        }
        String str = tobinaryString(num, 16);
        byte[] bytes = binaryIntToByte(str, 2);
        return bytes;
    }

    public static byte[] copy(byte[] dest, int start, byte[] source) {
        int end = start + source.length;
        if (end > dest.length || start > dest.length) {
            throw new RuntimeException("目标bytes长度：" + dest.length + "\t 开始字节：" + start + "\t 结束字节：" + end);
        }
        for (int i = 0; i < source.length; i++) {
            dest[i + start] = source[i];
        }
        return dest;
    }

    public static byte[] bufferToBytes(IoBuffer buffer) {
        byte[] bytes = new byte[buffer.position()];
        System.arraycopy(buffer.array(), 0, bytes, 0, bytes.length);
        return bytes;
    }

    public static byte[] bufferToBytes(IoBuffer buffer, int start, int length) {
        byte[] bytes = new byte[length];
        System.arraycopy(buffer.array(), start, bytes, 0, length);
        return bytes;
    }

    public static void printIoBuffer(String key, IoBuffer buffer, int pos) {
        int position = buffer.position();
        byte[] desc = new byte[position - pos];
        byte[] src = buffer.array();
        System.arraycopy(src, pos, desc, 0, position - pos);
        System.out.println();
        System.out.print(key+"\t");
        for (int i = 0; i < desc.length; i++) {
            System.out.print(StringUtils.leftPad(Integer.toHexString(desc[i]), 2, '0') + " ");
        }
        System.out.println();
    }

    public static void printIoBuffer(IoBuffer buffer, int pos) {
        int position = buffer.position();
        byte[] desc = new byte[position - pos];
        byte[] src = buffer.array();
        System.arraycopy(src, pos, desc, 0, position - pos);
        for (int i = 0; i < desc.length; i++) {
            System.out.print(StringUtils.leftPad(Integer.toHexString(desc[i]), 2, '0') + " ");
        }
    }

    public static void printIoBuffer(IoBuffer buffer) {
        int position = buffer.position();
        byte[] array = new byte[position];
        System.arraycopy(buffer.array(), 0, array, 0, position);
        for (int i = 0; i < array.length; i++) {
            System.out.print(StringUtils.leftPad(Integer.toHexString(array[i]), 2, '0') + " ");
        }
    }

    public static int calcOffset(byte[] offsetBytes, int type) {
        int offset;
        switch (type) {
            case 1:
                offset = keyBefore(offsetBytes);
                break;
            default:
                offset = digestBefore(offsetBytes);
                break;
        }
        return offset;
    }

    public static byte[] joinData(byte[] randomByte, int digestPos) {
        //| 4字节time | 4字节模式串 | 4字节offset | left[...] | 32字节digest | right[...] | 后半部分764字节 |
        //再说digest如何生成。
        //即将c1 digest左边部分拼接上c1 digest右边部分（如果右边部分存在的话）作为hmac-sha256的input（整个大小是1536-32），
        //1536-32=1504 digestPos join 加密数据
        byte[] digestJoin = new byte[1536 - 32];

        // digest左边部分  | 4字节time | 4字节模式串 | 4字节offset | left[...] digestPos包含了前面12个字节
        System.arraycopy(randomByte, 0, digestJoin, 0, digestPos);
        // digest右边部分， | right[...] | 后半部分764字节 |
        System.arraycopy(randomByte, digestPos + 32, digestJoin, digestPos, digestJoin.length - digestPos);
        return digestJoin;
    }

    public static byte[] calcSha256(byte[] digestBytes, byte[] key) {
        Mac hmac = null;
        try {
            hmac = Mac.getInstance("HmacSHA256");
            SecretKeySpec secret_key = new SecretKeySpec(key, "HmacSHA256");
            hmac.init(secret_key);
            return hmac.doFinal(digestBytes);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("不支持的加密方式");
        }
    }

    public static IoBuffer strToBuffer(String str) {
        try {
            byte[] bytes = Hex.decodeHex(str);
            IoBuffer ioBuffer = IoBuffer.allocate(str.length() / 2);
            ioBuffer.put(bytes);
            return ioBuffer;
        } catch (DecoderException e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
    }

    public static byte[] createRandomByte(int size) {
        Random random = new Random();
        BigInteger bigInteger = new BigInteger(size * 8 , random);
        byte[] handshakeBytes = BigIntegers.asUnsignedByteArray(bigInteger);
        if (handshakeBytes.length < size) {
            // resize the handshake bytes
            ByteBuffer b = ByteBuffer.allocate(size);
            b.put(handshakeBytes);
            b.put((byte) 0x13);
            b.flip();
            handshakeBytes = b.array();
        }
        return handshakeBytes;
    }

    /**
     * 当digest在前半部分时，digest的位置信息（以下简称offset）保存在前半部分的起始位置
     * c1格式展开如下：
     * | 4字节time | 4字节模式串 | 4字节offset | left[...] | 32字节digest | right[...] | 后半部分764字节 |
     * offset = (c1[8] + c1[9] + c1[10] + c1[11]) % 728 + 12
     * 计算出的offset是相对于整个c1的起始位置而言的。
     * 为什么要取余728呢，因为前半部分的764字节要减去offset字段的4字节，再减去digest的32字节。
     * 为什么要加12呢，是因为要跳过4字节time+4字节模式串+4字节offset。
     * offset的取值范围为[12,740)。
     * 当offset=12时，	left 部分就不存在，当offset=739时，	right 部分就不存在。
     *
     * @param offsetBytes
     * @return
     */
    public static int digestBefore(byte[] offsetBytes) {
        int c0 = offsetBytes[8] & 0xff;
        int c1 = offsetBytes[9] & 0xff;
        int c2 = offsetBytes[10] & 0xff;
        int c3 = offsetBytes[11] & 0xff;

        return (c0 + c1 + c2 + c3) % 728 + 12;
    }

    /**
     * 当digest在后半部分时，offset保存在后半部分的起始位置
     * | 4字节time | 4字节模式串 | 前半部分764字节 | 4字节offset | left[...] | 32字节digest | right[...] |
     * offset = (c1[8+764] + c1[8+764+1] + c1[8+764+2] + c1[8+764+3]) % 728 + 8 + 764 + 4
     * 计算出的offset依赖是相对于c1的其实位置而言的
     * 为什么要取余728呢，因为后半部分的764字节要减去offset字段的4字节，再减去digest的32字节
     * 为什么加8加764加4呢，是因为要跳过4字节time+4字节模式串+前半部分764字节+4字节offset
     * offset的取值范围为[776,1504)
     * 当offset=776时，	left 部分就不存在，当offset=1503时，	right 部分就不存在
     *
     * @param offsetBytes
     * @return
     */
    public static int keyBefore(byte[] offsetBytes) {
        int offset = 764 + 8;
        int c0 = offsetBytes[offset] & 0xff;
        int c1 = offsetBytes[offset + 1] & 0xff;
        int c2 = offsetBytes[offset + 2] & 0xff;
        int c3 = offsetBytes[offset + 3] & 0xff;

        return (c0 + c1 + c2 + c3) % 728 + 8 + 764 + 4;
    }

    public static byte[] fillRandomByte(byte[] randomByte, int digestType, int offset, byte[] digestKey, int length) {
        //| 4字节时间戳time | 4字节模式串 | 1528字节复杂二进制串 |
        //| 4字节time | 4字节模式串 | 4字节offset | left[...] | 32字节digest | right[...] | 后半部分764字节 |
        //再说digest如何生成。
        //即将c1 digest左边部分拼接上c1 digest右边部分（如果右边部分存在的话）作为hmac-sha256的input（整个大小是1536-32），
        // 以下大小为30字节固定key作为hmac-sha256的key，进过hmac-sha256计算得出32字节的digest填入c1中digest字段中。
        byte[] digestJoin;
        switch (digestType) {
            case 0:
                digestJoin = Utils.joinData(randomByte, offset);
                break;
            default:
                //todo
                throw new RuntimeException("//todo key first");
        }

        //以固定大小为30字节固定key作为hmac-sha256的key，进过hmac-sha256计算得出32字节的digest填入c1中digest字段中。
        byte[] key = Arrays.copyOf(digestKey, length);
        //digest 值
        byte[] array = Utils.calcSha256(digestJoin, key);
        //填充32位digest
        System.arraycopy(array, 0, randomByte, offset, 32);
        return array;
    }

    public static byte[] fillRandomByte(byte[] randomByte, int digestType, byte[] digestKey, int length) {
        //digest在前，计算offset位置
        int digestPos = Utils.calcOffset(randomByte, digestType);
        System.out.println("digestPos========"+digestPos);
        return fillRandomByte(randomByte, digestType, digestPos, digestKey, length);
    }

    public static byte[] digestJoin(byte[] bytes, int offset) {
        //1536 - 32 去除32位 digest
        byte[] join = new byte[1536 - 32];

        int srcPos = 0;
        int destPos = 0;
        int destEnd = offset;

        //left 0,offset start:0
        System.arraycopy(bytes, srcPos, join, destPos, destEnd);

        srcPos = offset + 32;
        destPos = offset;
        destEnd = join.length - offset;

        System.arraycopy(bytes, srcPos, join, destPos, destEnd);
        return join;
    }

    public static void main(String[] args) {
        String str = "000000058000070264dccd773de0e0690f69962f5c660f5970a693764167062a2d0844ca6ef3d6cd1421e72ae3d7a9779a7319b8de9aba002fb92d0fb2a2843c388cc07de39a8824c0f9f889e5eb51700cdba0e43574dee7bec46d72a03540713128eeb0f467eed527c5a57976ea5cf10e0d9580c96f84ac596eed3a2f8ccfcdcbf521b04b14a04ca11c1240ca8ad27500469273a3c56a20112b19aec507b4e9af94c613719aa8c39612f2fa9b09091e74334821f1983bd549e642bb8de3e1c8fa74838959ee2fe705c18f99a5d57666b166bba786b849f939f8f202f728b0f4bdf1126ed645731efe27a542294c5d613197529857eff4596b6cf13136b422927c3bd1f020f14d44285c236f6e855eef23b5592bffe417234198c130c048c060b0124ed154c3d4393c05414c3b315023e9cbe4783c8e21bd6d018a45d2b5660145526bc6f10ac6ec872c6a285f83dd759bb43cf56f2dbcfd7694a24bea0acfa01c4ad2455b1ad0216c5bebc72a30caad83983f4a20e323b93a2b43914bdcb3258ae9c9b15b60f090e009727ff178e8699f435faa78ce8ea467630cc17c97cb4ed8b9b7ea9d106da8ed5cbcdb8d48140a234727e5c6bd486400c5647ac9e708c1c1a8d5e0305c2b992f35126fdc5fc54cf4eb74d8fb6e6492de38e4e0c12ad3e2f6a2e6090a3a64255a8d61163f920a572df5ca542d6024852ccf4778b6f428859dfef38d82bff908b22818a91b1200059e326b2e17307d9eead5a71740a5dec7ceb55d95d408efb89191149058cd125148e31f00988e53f86c3fea9bba0b6b5a1571c761a1b1c4a5e4674831e5d9a258e2e7de1730bd5753d858ab46c41bf436f361acc26cddbb22afffe57632f2d60457c5b020869fa048abd01664bfb18d395deda3051dd04192854f33fab401b3a67ae89fa69388ae38af2558894c1f8d1d391bc770b251ad9418d07e1731d3717a8112e1cbb98b8cda18d3202bed778e61ea17b77bc93e7dcf8fe5dda04064f1388e378ac416fcb327cd3bf1e63bb55cb6bbe02b8b0821d27353086612c9534bc12955a41332fe3b4c1ffc33bbae8b85f2729ce411b6b7875441a93ea484fcdec6c0badf92e6474fa8adfa4f660017f4c2c71e74e52f884db453d5a1e179aaeb47f67aa9033264c8ea6c3638d6ab468536e87d5604339bc8ad17638eb5b7750503201e85c6b6b3c14624fd2ecd6e121d86f56c233a670553c82e11f8aace3ef924cb24fa7f3afdf45dee7149beccbe7d218366c124d2fff354cef46cfe53bb834b345abf3b268e4c34bc636ddb8c3113711aa7e34b6290128c41388a1c60922ddecef60d4a0aeb47ebd173c30b3a5624d1b7f75c1b65c2a4326429da791189ded6c09246e618101676458cd7a6a5921ca74b481158106fdde32998f5e908bff9f364e851b1a54187f182a6e15d5f4bdf15391a9016fc959afa158502bde9fa14f6ca66672dac6c38cdcae1f0b1407857c2dcbaa151a345167cc21feaf3df069dfb329423b44a179a7daee9f2b2e448b54dff4d51fee7139c535e15e0cc151df944964018d343e1b40098acd18828d90ba763a83de28c2645a52b2f15c33e64ffab1e8840967c94cd1942622175b0f5401a3cfa3a80b9cbfcfbfd40afdd0e7ccce1a9a5020b7fc54aca3de2189164f0800eb4498f267ba24f9dbf6760d3bf1950164b95a931fa037e386c4ace88ef84a8ba67bd53894353c75bee9737198db42005c98680a6409b32e786f5f1f93fcd56b2e6b6c45a63d8d4d61c7c846c3a4268831f20fa86c6e223db97c181e90846991234bd8a0294568b356ea3e8c88b03fc92fa8f8d7aa71ebd0d7fa62ef941e363414c3746ec7285ad0f1f00f004c860f1ae3f70335221f0c456719c6ea2a53447a799f6e7e4fea7cf66fbb5ca8040d6417e8278ac641656d6c876d274c2329a16877b91a0a51c159047e538026cc3f04f599000fca88c3dc956e8348a2fae88701bc98d70fa135028e951bb4328265a5f17e552c0932da26c7af74380e51dde5a6e4a5ba3e910b1d8e7caec9938c3f5516936cf52e7c83e347f273a38944c4665f33b1ebfe0a29df0846d08b0fdf60c3c9fe9dcd9f9cecdbb05d08278004aaf03c9cc49b3323f5175ad6c33f838a18ba11698adb66fd6d9414f9d808ab4e9cd12aa";
        IoBuffer ioBuffer = Utils.strToBuffer(str);
        byte[] s1 = ioBuffer.array();
        String enc = Hex.encodeHexString(s1);
        System.out.println("s1："+enc);
        System.out.println(enc.equals(str));

        byte[] digest = Utils.fillRandomByte(s1, 0, Constant.GENUINE_FP_KEY, 30);
        String test = Hex.encodeHexString(digest);
        System.out.println("digest："+test);
        String s1d = "7ae89fa69388ae38af2558894c1f8d1d391bc770b251ad9418d07e1731d3717a";
        System.out.println(s1d.equals(test));

        String str2 = "9c6baf3a1bf03465252d3aa202c1fdfb274f268a6bcd19007aef67d126cef5c23aa4fc559530bbba5ef55c60b7595bdea88168134e8113c9717a9a97498f5a833456d8c9879383e589df454038a01ee02286f3700707397881d310ca636a4d97c0266047b9e32c42c27182fa12a0da3426cda42ed4dea656b1b62014206eabe1940b284dee5590b0c612aad8b3840cd952b107268fae7c40649d55850b00669f0c8eecfae37cabaa8f558242da8f1b2c402352cfd1cf0f356c64ba7765201671af026b927f163c0e6cbf50464e6b728e8ec45d5f936c95ffd14f7636708ca71f8f12b10e29ee1c95ad6cdbfbd74d896611e6c5a5525aa423aa1b591aa700393613ea443cd860d185ccac80a4f9090a0aefcfaf422a5465d46fbfee16bf274dd211910eeaf2df6fbe8bf06284f96c8fe93c3e2b6692903a014f28180f4f65e160f6f04ae8cfbaa75baa09dfa3766e8cb2adb7183f485241977a59a6c9be8829b478749d472e44a2d84d827bc3f008759dbf8ddd07df1e9f5977452235cd4ce945c0868deeca2fc618b141dba249513f09de1c10be3aaf17b1f53ae6c286d0084656953421c4fa39763b14188565578e44749e02ae4e196043534605d9160d1f6da2538e674dc7dd89dbf50e414c9c85c03a876f88a0cfcbf415d1cd2cdeed99814027e88eeec517c9ba250a06c18fc7fb163684b7054fab1a207846ff65df80a6066834f42d4bbee770c8ed3158b42c6eeab025ef00d00a2049501fae309f543607882b34d3e91b43b1097409bda178a8519d97516ea172b7f291652231ba583842836d166c88591e91ce274f6f9ff7c03d8e12ab3084622215c74446819c7fc420ecda8c7433aa0601d25570714c31aeda43590ac7bb2cdc837023040da2c82d8ea2b902d66408d7365d48a7a9795684bcaf8e836bbb5fee2b82f23824bb65b25d1fb53383bd0bb91b5360c4ccb6488866d70bd1926abfbdedb1f6116c5bc4ca7a79fdfd3608b6515b171627cd5eaf3335ba04c725c38512757b23e1d6e7ab5160a94e97b105e80d1cfe34e95de41d929e215ac3e5dfd55a5af93b30e0e7814190d0d841d5c04ef1bf83da1c67f7ae051908c9fee79e5841979372787af3b90ac3914c98519a89101d642c845bdb8a74e35372cbf1ca0c895e7e01d872bae3354b2fce9cc957ade7bbd96b17b4f58b9848fe633ac86fc326eec4ff607ee295c9116365dabb12c176ec2d8da02219386b179ba5df0b6806f92c0559aae7ee73f852d8d20deb9483d7c11177e32ab04e414bf320565b264f872ba8311297a40ae97dddf66871793f328ab615b46664f5b2571608b33c583a68006c7a971085808d6276f5d3f034057aeb1a2f517e2403d63a0c897764c3df642f59fc40de7ccd40f3c313e3f7185de2338c34b1b13787eb431062a7d4410c039b0843798411ba77d4cd5acbe6b8ae1944e2caf51952e15d6243043685103a20187d999d8e531462216f2e0727dc206bbeea61d73c42349f8539d50a490f2a628dc4ff1b17137e3882ac3fa9885f15464a761d86b852253d8bfb48d40a7236973635b34e493186cbddc67565258aab6f00c8f6b81a1bf5a5163d7a21b0b0b8e6e66b342f9cbbfa79816fdea6f98916f9520cb16c27a7123ee48c5f943c177b2283af511f6a4c99ebbb7792b501a8ae53b460bfdb07d119eb5d78809a90fbbc13aa0e32155acb00154392ca443a7997eed956cae028e3cb855c4b1fec46dcfff1ea310644fd065940992484d39d1bc276718c56996f211fcb6d3eb7b31ab6a404e8aa48e5b1a2254ac6a91d63c4dfd9356b2fcfdb50eea6bd2c5e714714154bfcc094e1713606bbfcafd85f73b838a9236778feb766a5759203e6d917fb2514bbb9f52ceffce7ebabc04a1f7882c89be9409aa0a63f153842fb1259f7376db2f063dfdf5fc6ca0a861429fe96f19a7f31341fd7733510b530220e27597cda49dfb9283e7ff248060672049c639e1b95d23a6c456f7cfaa09e09c7f785a140645a68a2da5aeae0605ce4fcc08317555552c19bc13e9561dc9e29d423ca1487257d29ffd714df3870c33430464c859c9e47375f85ccc1616bea358eb44a16d9c73fd89e53b7d6c47b0b3a4957584eedfcea4c3ebb864deee6e978c85c10dc9fdd2f508077086adfa3b9";
        IoBuffer s2Buffer = Utils.strToBuffer(str2);
        byte[] s2 = s2Buffer.array();

        System.out.println("S2："+Hex.encodeHexString(s2));

        byte[] calcBytes = new byte[s2.length - 32];

        System.arraycopy(s2, 0, calcBytes, 0, calcBytes.length);
        //calculateHMAC_SHA256(c1, digestPosClient, DIGEST_LENGTH, GENUINE_FMS_KEY, GENUINE_FMS_KEY.length, digest, 0);
        //hmac.init(new SecretKeySpec(Arrays.copyOf(key, keyLen), "HmacSHA256"));
        //byte[] actualMessage = Arrays.copyOfRange(message, messageOffset, messageOffset + messageLen);
        //byte[] calcDigest = hmac.doFinal(actualMessage);
        int digestPos = Utils.calcOffset(s1, 0);
        byte[] s1data = new byte[32];
        System.arraycopy(s1, digestPos, s1data, 0 , s1data.length);
        byte[] kkkk = Arrays.copyOf(Constant.GENUINE_FMS_KEY, Constant.GENUINE_FMS_KEY.length);
        byte[] s1Digest = Utils.calcSha256(s1data, kkkk);


        System.out.println(Hex.encodeHexString(s1Digest));
        System.out.println("ff85bae675b8f8a40fd6868275943dc0dcdd606d940d0f6814a99bb9d351ea00");
        System.out.println(Hex.encodeHexString(s1Digest).equals("ff85bae675b8f8a40fd6868275943dc0dcdd606d940d0f6814a99bb9d351ea00"));

        byte[] result = Utils.calcSha256(calcBytes, s1Digest);
        System.out.println(Hex.encodeHexString(result));
        System.out.println("5f2e2baeae87a074ca914862ac39b44836b7fd96338e928dc09262b5e10a8e84");
    }
}
